package com.jiao.table.listener;

import cn.hutool.core.collection.CollectionUtil;
import com.jiao.comm.exception.CloseLoopException;
import com.jiao.comm.exception.ListenerException;
import com.jiao.datasource.parse.SQLCommand;
import com.jiao.datasource.parse.SQLParse;
import com.jiao.datasource.parse.SQLStruct;
import com.jiao.datasource.parse.SQLUnitAbstract;
import com.jiao.datasource.parse.WriteSQLUnit;
import com.jiao.table.cache.CacheWrite;
import com.jiao.table.cache.DynamicCacheRead;
import com.jiao.table.cache.DynamicCacheWrite;
import com.jiao.table.config.CacheDataLoad;
import com.jiao.table.entity.TableInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

import static com.jiao.datasource.parse.SQLStruct.*;

/**
 * @Description
 * @Author Vincent.jiao
 * @Date 2022/5/13 17:00
 */
@Component
public class UpdateSQLListener extends WriteSQLListenerAbstract {
    @Autowired
    DynamicCacheWrite cacheWrite;

    @Autowired
    DynamicCacheRead cacheRead;

    /**
     * 提交前执行.
     * 在提交前获取受影响的行id，然后再更新 redis.
     * @param sqlCommands
     * @throws RuntimeException
     */
    @Override
    public void commiteBefore(List<SQLCommand> sqlCommands) throws ListenerException {
        updateData(sqlCommands);
    }

    @Override
    public void execAfter(SQLCommand commandInfo) {
        if(commandInfo.getSqlUnit().isAutoCommit()) {
            //如果自动提交就触发闭环
            updateData(Arrays.asList(commandInfo));
        }
    }

    public void updateData(List<SQLCommand> sqlCommands) {
        List<SQLCommand> updateCommandList = new LinkedList<>();
        for (SQLCommand item : sqlCommands){
            if(!isUpdate(item)) {
                continue;
            }
            if(!isExceCloseLoop(item)) {
               continue;
            }

            updateCommandList.add(item);
        }

        if(CollectionUtil.isEmpty(updateCommandList)) {
            return;
        }

        for (SQLCommand item : updateCommandList){
            try {
                int count = getWriteCount(item);
                if(count == 0) {
                    continue;
                }

                List<Long> ids = getWriteRowId(item);
                List<Object> datas = getDataById(item, ids);
                cacheWrite.updateBatch(datas);

            } catch (SQLException e) {
                throw new ListenerException(e.getMessage(), e);
            }
        }
    }
}
